package ch.rheintalconnection.sysventory.technicalServices.wmi;

import java.net.ConnectException;
import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import ch.rheintalconnection.sysventory.dto.ComputerDto;
import ch.rheintalconnection.sysventory.dto.DtoContainer;
import ch.rheintalconnection.sysventory.dto.LogicalDiskDto;
import ch.rheintalconnection.sysventory.dto.NicDto;
import ch.rheintalconnection.sysventory.dto.OperatingSystemDto;
import ch.rheintalconnection.sysventory.dto.PrinterConfigurationDto;
import ch.rheintalconnection.sysventory.dto.PrinterDto;
import ch.rheintalconnection.sysventory.dto.ProcessorDto;
import ch.rheintalconnection.sysventory.dto.ProgramDto;
import ch.rheintalconnection.sysventory.technicalServices.IHostScanner;

import com.jacob.activeX.ActiveXComponent;

public class WMIHostScanner implements IHostScanner {

	private String host;
	
	private NICScan nicscan;
	private ComputerScan computerScan;
	private OperatingSystemScan operatingSystemScan;
	private PrinterScan printerScan;
	private ProcessorScan processorScan;
	private ProgramScan programScan;
	private LogicalDiskScan logicalDiskScan;
	private PrinterConfigurationScan printerConfigurationScan;
	
	private static Logger logger = LogManager.getLogger(WMIHostScanner.class);
	
	public WMIHostScanner(String host){
		
		this.host = host;
		
		String connectStr = String.format("winmgmts:\\\\%s\\root\\CIMV2", host);
		ActiveXComponent axWMI = new ActiveXComponent(connectStr);
		
		nicscan = new NICScan(axWMI, host);
		computerScan = new ComputerScan(axWMI, host);
		logicalDiskScan = new LogicalDiskScan(axWMI, host);
		operatingSystemScan = new OperatingSystemScan(axWMI, host);
		printerScan = new PrinterScan(axWMI, host);
		printerConfigurationScan = new PrinterConfigurationScan(axWMI, host);
		processorScan = new ProcessorScan(axWMI, host);
		programScan = new ProgramScan(axWMI, host);
	}
	
	public DtoContainer scan() throws ConnectException {
		
		NicDto nicDto = scanNic();
		log(nicDto);
		
		ComputerDto computerDto = scanComputer();
		log(computerDto);
		
		LogicalDiskDto logicalDiskDto = scanLogicalDisk();
		log(logicalDiskDto);
		
		OperatingSystemDto operatingSystemDto = scanOperatingSystem();
		log(operatingSystemDto);
		
		ProcessorDto processorDto = scanProcessor();
		log(processorDto);
		
		logger.debug("\r\n" + host + "- START PRINTER-SCAN");
		List<PrinterDto> printerDtos = scanPrinters();
		List<PrinterConfigurationDto> printerConfigurationDtos = scanPrinterConfigurations();
		logger.debug("\r\n" + host + "- END PRINTER-SCAN" + "\r\n");
		
		logger.debug("\r\n" + host + "- START PROGRAM-SCAN");
		List<ProgramDto> programDtos = scanPrograms();
		logger.debug("\r\n" + host + "- END PROGRAM-SCAN" + "\r\n");
		
		return new DtoContainer(nicDto, computerDto, logicalDiskDto, operatingSystemDto, processorDto, printerDtos, printerConfigurationDtos, programDtos);
	}

	protected NicDto scanNic() throws ConnectException {
		
		return nicscan.scan();
	}

	protected ComputerDto scanComputer() throws ConnectException {
		return computerScan.scan();
	}

	protected LogicalDiskDto scanLogicalDisk() throws ConnectException {
		return logicalDiskScan.scan();
	}

	protected OperatingSystemDto scanOperatingSystem() throws ConnectException {
		return operatingSystemScan.scan();
	}
	
	protected ProcessorDto scanProcessor() throws ConnectException {
		return processorScan.scan();
	}

	protected List<PrinterDto> scanPrinters() {
		return printerScan.scan();
	}
	
	protected List<PrinterConfigurationDto> scanPrinterConfigurations() {
		return printerConfigurationScan.scan();
	}
	
	protected List<ProgramDto> scanPrograms() {
		return programScan.scan();
	}

	@Override
	public String toString() {
		return "WMIHostScanner [host=" + host + "]";
	}
	
	private void log(Object dto) {
		logger.debug(host + " scanned \r\n" + dto + "\r\n");
	}
}
